package com.yhb.example;

import com.alibaba.fastjson.JSONObject;
import com.yhb.config.PayConfig;
import com.yhb.exception.AuthorizationException;
import com.yhb.exception.InvalidRequestException;
import com.yhb.exception.InvalidResponseException;
import com.yhb.model.HttpUtil;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

public class PayExample {

   private static final DateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");

    public static void main(String[] args) {
        // 下单
//        orderCreate();
        // 订单查询
//        orderQuery();
        // 退款申请
//        orderRefundApply();
        // 退款查询
//        orderRefundQuery();
        // 交易明细查询
        tradeDetailQuery();
    }

    /**
     * 下单
     */
    private static void orderCreate() {
        Map<String, Object> orderReqMap = new HashMap<String, Object>();
        // 商户系统内部订单号，要求64个字符内，只能是数字、大小写字母_-|* 且在同一个商户号下唯一
        orderReqMap.put("merchant_order_no", "M"+ UUID.randomUUID().toString().replaceAll("-",""));
        // 购买商品的标题，不同支付类型的长度要求不同，具体如下：微信扫码支付：128字节 支付宝扫码支付：128字节
        orderReqMap.put("product_title", "收款");
        // 购买商品的描述信息，要求128个字符内
        orderReqMap.put("product_desc", "收款满10减1");
        // 符合ISO 4217标准的三位字母代码，默认人民币：CNY
        orderReqMap.put("currency", "CNY");
        // 订单总金额，单位为分
        orderReqMap.put("amount", "1000");
        // 订单描述，要求300个字符内，不能包含特殊字符:英文逗号，注意：下载对账单会返回此字段数据
        orderReqMap.put("description", "扫码测试");
        // 交易类型:微信扫码支付:wechat_csb 支付宝扫码支付:alipay_csb 注:区分大小写
        orderReqMap.put("trade_type","alipay_csb");
        // 订单生成时间，格式为yyyyMMddHHmmss
        orderReqMap.put("time_start",sdf.format(new Date()));
        // 敏感字段加密时使用的密钥，如果报文中有敏感字段，此字段必传，注意:RSA加密之前密钥原文固定16个字节
        orderReqMap.put("encrypted_key", "");
        //下单用户IP，可提高支付订单成功率
        orderReqMap.put("user_ip", "27.156.89.12");
        // 订单异步通知URL 注意:订单状态为成功或失败时都会通知该URL
        orderReqMap.put("notify_url", "https://merchant.notify.com");
        // 支付模式 为空或为1 则为 纯api模式 2 收银台模式
        orderReqMap.put("pay_mode", "1");
        // 商品名称 支付模式 为2 收银台模式时，必填
        orderReqMap.put("partition_name", "");
        // 充值帐号 支付模式 为2 收银台模式时，必填
        orderReqMap.put("game_account", "");
        // 前台通知URL 支付模式 为2 收银台模式时 支付成功后，平台才会同步通知到该URL
        orderReqMap.put("front_url", "");

        List<Map<String,Object>> splitDetailsList = new ArrayList<>();
        Map<String,Object> splitDetailMap = new HashMap<>();
        splitDetailMap.put("merchantId","123");
        splitDetailMap.put("splitAmt", "8.2");
        splitDetailsList.add(splitDetailMap);
        orderReqMap.put("splitDetails",JSONObject.toJSONString(splitDetailsList));

        String reqStr = JSONObject.toJSONString(orderReqMap);
        System.out.println("下单请求参数:"+ reqStr);

        try {
            Map<String, String> result = HttpUtil.request(PayConfig.API_BASE_URL+ PayConfig.ORDER_CREATE,reqStr);
            System.out.println("下单响应报文:\n"+result);
        } catch (AuthorizationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InvalidRequestException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        }
    }

    /**
     * 订单查询
     */
    private static void orderQuery() {
        Map<String, Object> orderReqMap = new HashMap<String, Object>();
        // 商户系统内部订单号，要求64个字符内，只能是数字、大小写字母_-|* 且在同一个商户号下唯一
        orderReqMap.put("merchant_order_no","");
        // 支付平台订单号
        orderReqMap.put("order_no","PD201911081009355181265408000");

        String reqStr = JSONObject.toJSONString(orderReqMap);
        System.out.println("订单查询请求参数:"+ reqStr);

        try {
            Map<String, String> result = HttpUtil.request(PayConfig.API_BASE_URL+ PayConfig.ORDER_QUERY,reqStr);
            System.out.println("订单查询响应报文:\n"+result);
        } catch (AuthorizationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InvalidRequestException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        }
    }

    private static void orderRefundApply() {
        Map<String, Object> reqMap = new HashMap<String, Object>();
        // 商户系统内部退款订单号，要求64个字符内，只能是数字、大小写字母_-|* 且在同一个商户号下唯一
        reqMap.put("merchant_refund_order_no", "MR"+ UUID.randomUUID().toString().replaceAll("-",""));
        // 退款金额，单位为分
        reqMap.put("amount", "1");
        // 商户退款申请时间 格式:yyyyMMddHHmmss
        reqMap.put("merchant_refund_apply_time",sdf.format(new Date()));
        // 退款描述，要求300个字符内，不能包含特殊字符:英文逗号，注意：下载对账单会返回此字段数据
        reqMap.put("description", "退款描述");
        // 注意:商户原订单号或平台原订单号至少有一个数值不允许为空值
        // 商户原订单号
        reqMap.put("merchant_order_no","");
        // 平台原订单号
        reqMap.put("order_no","PD201911081009355181265408000");

        String reqStr = JSONObject.toJSONString(reqMap);
        System.out.println("退款申请请求参数:"+ reqStr);

        try {
            Map<String, String> result = HttpUtil.request(PayConfig.API_BASE_URL+ PayConfig.REFUND_APPLY,reqStr);
            System.out.println("退款申请响应报文:\n"+result);
        } catch (AuthorizationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InvalidRequestException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        }
    }

    private static void orderRefundQuery() {
        Map<String, Object> reqMap = new HashMap<String, Object>();
        // 注意：以下4个参数必须有一个不允许为空值
        // 商户系统内部订单号
        reqMap.put("merchant_order_no","");
        // 支付平台订单号
        reqMap.put("order_no","");
        // 商户系统退款订单号
        reqMap.put("merchant_refund_order_no","");
        // 支付平台退款订单号
        reqMap.put("refund_order_no","PR201911081028079842512883712");

        String reqStr = JSONObject.toJSONString(reqMap);
        System.out.println("退款查询请求参数:"+ reqStr);

        try {
            Map<String, String> result = HttpUtil.request(PayConfig.API_BASE_URL+ PayConfig.REFUND_QUERY,reqStr);
            System.out.println("退款查询响应报文:\n"+result);
        } catch (AuthorizationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InvalidRequestException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        }
    }

    private static void tradeDetailQuery() {
        Map<String, Object> orderReqMap = new HashMap<String, Object>();
        // 开始时间 格式：yyyy-MM-dd HH:mm:ss
//        orderReqMap.put("startTime","2024-05-03 11:22:32");
        // 结束时间 格式：yyyy-MM-dd HH:mm:ss
//        orderReqMap.put("endTime","2024-05-03 11:22:32");
        // 第几页
        orderReqMap.put("pageNum",1);
        // 每页条数
        orderReqMap.put("pageSize",50);

        // 商户系统内部订单号
        orderReqMap.put("merchant_order_no","");
        // 支付平台订单号
        orderReqMap.put("order_no","");

        String reqStr = JSONObject.toJSONString(orderReqMap);
        System.out.println("交易明细查询请求参数:"+ reqStr);
        try {
            Map<String, String> result = HttpUtil.request(PayConfig.API_BASE_URL+ PayConfig.TRADE_DETAIL_QUERY,reqStr);
            System.out.println("交易明细查询响应报文:\n"+result);
        } catch (AuthorizationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InvalidRequestException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        }
    }
}
